/*
 * =====================================================================================
 *
 *       Filename:  prop.c
 *
 *    Description:  read properties file
 *
 *        Version:  1.0
 *        Created:  2011年11月16日 00时43分28秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  wutao (wt), 363697339@qq.com
 *        Company:  北京恺英网络创新科技有限公司
 *
 * =====================================================================================
 */
#include "prop.h"
#include "resource.h"
#include "buffer.h"

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <memory.h>

void add_buff_to_prop(struct buffer *buff, struct prop *cnf) {
	struct buffer *temp = cnf->props;
	if (temp == NULL) {
		cnf->props = buff;
		return;
	}

	while (1) {
		if (temp->next == NULL)
			break;
		temp = temp->next;
	}

	//printf("debug add buff to \n");
	temp->next = buff;
}

void free_buffer(struct buffer *begin, struct bufferFactory *factory) {
	struct buffer *temp;
	while (begin) {
		temp = begin;
		buffer_del(factory, temp);
		begin = begin->next;
	}

}
/* -----  end of function free_buff  ----- */
int read_prop(const char *file, struct prop *cnf) {
	int fd = open(file, O_RDONLY);
	if (fd == -1) {
		return 1;
	}

	struct buffer *buff_begin = NULL;
	struct buffer *buff_cur = NULL;

	struct bufferFactory *factory = get_bufferFactory();

	int loop = 1;
	do {
		struct buffer *buff = buffer_new(factory);

		ready_to_read(buff);
		if (buff_begin == NULL) {
			buff_begin = buff;
			buff_cur = buff;
		} else {
			buff_cur->next = buff;
		}

		u_int32_t offset = 0;
		while ((buff->length) - offset) {
			ssize_t readed = read(fd, (buff->data) + offset,(size_t)
					((buff->length) - offset));
			if (readed == -1) {
				buffer_del(factory, buff);
				return 1;
			}
			if (readed == 0) {
				loop = 0;
				break;
			}
			buff->index += readed;
			buff->limit = buff->index;
			offset += readed;
		}

	} while (loop);
//printf("parse file \n");	
	buff_cur = buff_begin;
	struct buffer *buff_prop = NULL;
	while (buff_cur) {
//printf("loop propline %s\n",buff_cur->data);
		int cur = 0;
		u_int32_t begin = 0;
		while (1) {
			if (buff_cur->data[cur] == '\n') {

				if (buff_prop == NULL) {
					buff_prop = buffer_new(factory);
					//printf("buff_prop new addr is %p\n",buff_prop);
					ready_to_read(buff_prop);
				}

				memcpy((buff_prop->data) + (buff_prop->index),
						(buff_cur->data) + begin, cur - begin);
				buff_prop->index += cur - begin;
				buff_prop->limit = buff_prop->index;
				add_buff_to_prop(buff_prop, cnf);
				buff_prop = NULL;
				begin = cur + 1;

			}
			cur++;
//printf("debug char %c curr%d limit%d\n",buff_cur->data[cur-1],cur,buff_cur->limit);		
			if (cur == buff_cur->limit) {
				if (buff_prop == NULL) {
					buff_prop = buffer_new(factory);
					ready_to_read(buff_prop);
				}
				//printf("debug ==limit n");
				memcpy(buff_prop->data, (buff_cur->data) + begin, cur - begin);
				buff_prop->limit = cur - begin;
				buff_prop->index = cur - begin;
				break;
			}

		}
		buff_cur = buff_cur->next;
	}
	add_buff_to_prop(buff_prop, cnf);
	free_buffer(buff_begin, factory);
	return 0;
}

const char* get_prop(struct prop *cnf, const char *key) {
	size_t len = strlen(key);
	if (len == 0) {
		return NULL;
	}
	struct buffer *temp = cnf->props;
	while (temp) {
		//printf("prop %s\n",temp->data);
		if (temp->limit < len) {
			temp = temp->next;
			continue;
		}

		int i = 0;
		char temp_c = (temp->data)[i];
		char key_c = key[i];

		while (key_c != '\0') {
			//printf("cmp %c %c \n",key_c,temp_c);
			if (temp_c != key_c) {
				break;
			}
			i++;
			//printf("index cmp len%d index%d \n",len,i);
			if (len == i) {
				//printf("that is the letter %c \n",temp->data[i+1]);
				return (temp->data) + i + 1;
			}
			temp_c = (temp->data)[i];
			key_c = key[i];
		}
		temp = temp->next;
	}

	return NULL;
}
